/*
 * Created on Mar 7, 2005
 */
package org.vectrics.html.menu;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import org.apache.ecs.html.A;
import org.apache.ecs.html.IMG;
import org.apache.log4j.Logger;
import org.vectrics.common.html.Cell;
import org.vectrics.common.html.Row;
import org.vectrics.common.html.Table;
import org.vectrics.common.html.TextHelper;
import org.vectrics.domain.Domain;
import org.vectrics.hibernate.ThreadProperties;
import org.vectrics.provider.CoreServiceLocator;
import org.vectrics.struts.VectricsTagSupport;
import org.vectrics.web.menu.Menu;
import org.vectrics.web.menu.MenuConfigReader;
import org.vectrics.web.menu.MenuItem;

/**
 * @author MMoore
 */
public class MenuTag extends VectricsTagSupport {
    public static final long serialVersionUID = 119935787325326L;

    private String id = null;

    private transient Logger log = Logger.getLogger(this.getClass());

    private String selectedItemId = null;

    private int itemWidth = 100;

    private int itemHeight = 17;

    private int subItemWidth = 165;

    private int subItemHeight = 15;

    private int itemCellSpacing = 1;

    public MenuTag() {
        super();
    }

    /**
     * Determines if a menu item will be displayed. This method can be
     * overridden by derived class to hide certain menu items from user.
     * 
     * @param The
     *            menu item in question.
     * @return True if item can be displayed.
     */
    protected boolean allowItemToBeDisplayed(final MenuItem child) {
        return true;
    }

    @Override
    protected String makeStartTag() {
        Table menuTable = new Table();
        menuTable.setCellSpacing(0);
        menuTable.setCellPadding(0);
        MenuItem selectedItem = null;
        Row topRow = menuTable.addRow();
        Cell topCell = topRow.addCell();
        Table innerTable = new Table();
        topCell.addElement(innerTable);
        innerTable.setCellPadding(0);
        innerTable.setCellSpacing(1);
        Row innerRow = innerTable.addRow();

        Menu menu = getMenu();
        List itemsList = removeItemsUserNotAuthorizedToView(menu.getChildList());
        Iterator iter = itemsList.iterator();
        while (iter.hasNext()) {
            MenuItem child = (MenuItem) iter.next();

            Cell childCell = innerRow.addCell();
            allowItemToBeDisplayed(child);
            // childCell.setBgColor("#ffff00");
            childCell.setWidth(0);
            boolean selected = false;
            if (child.getId().equals(getSelectedItemId())) {
                selected = true;
            }
            boolean highlighted = false;
            boolean submenu = false;
            childCell.addElement(getMenuItemHtml(menu, child, submenu, selected, highlighted, getLocale()));

            if (child.getId().equals(getSelectedItemId())) {
                selectedItem = child;
            }

        }

        if (selectedItem != null) {
            Row subRow = menuTable.addRow();
            Cell subCell = subRow.addCell();
            innerTable = new Table();
            subCell.addElement(innerTable);
            innerTable.setCellPadding(0);
            innerTable.setCellSpacing(itemCellSpacing);
            innerRow = innerTable.addRow();

            List childList = removeItemsUserNotAuthorizedToView(selectedItem.getChildList());
            removeItemsUserNotAuthorizedToView(childList);
            int selectItemLeft = childList.indexOf(selectedItem) * itemWidth;
            int mainMenuWidth = menu.getChildList().size() * itemWidth;
            int childMenuWidth = childList.size() * (subItemWidth + itemCellSpacing);

            int childMenuLeft = selectItemLeft;
            if (childMenuLeft + childMenuWidth > mainMenuWidth) {
                childMenuLeft = mainMenuWidth - childMenuWidth;
            }
            if (childMenuLeft < 0) {
                childMenuLeft = 0;
            }

            if (childMenuLeft > 0) {
                Cell spacerCell = innerRow.addCell();
                IMG spacerImg = new IMG();
                spacerImg.setSrc("/hrs-intranet/graphics/cleardot.gif");
                spacerImg.setHeight(1);
                spacerImg.setWidth(childMenuLeft);
                spacerCell.addElement(spacerImg);
            }

            iter = childList.iterator();
            while (iter.hasNext()) {
                MenuItem child = (MenuItem) iter.next();
                Cell childCell = innerRow.addCell();
                childCell.setWidth(0);
                // childCell.setBgColor("#ff0000");

                boolean selected = false;
                if (child.getId().equals(getSelectedItemId())) {
                    selected = true;
                }
                boolean highlighted = false;
                childCell.addElement(getMenuItemHtml(menu, child, true, selected, highlighted, getLocale()));
            }
        }
        return menuTable.toString();
    }

    private List removeItemsUserNotAuthorizedToView(final List itemList) {
        List newList = new ArrayList();
        Iterator iter = itemList.iterator();
        while (iter.hasNext()) {
            MenuItem item = (MenuItem) iter.next();
            boolean canDisplay = allowItemToBeDisplayed(item);
            if (canDisplay) {
                newList.add(item);
            }
        }
        return newList;
    }

    @Override
    public String getId() {
        return id;
    }

    @Override
    public void setId(final String id) {
        this.id = id;
    }

    protected Menu getMenu() {
        log.debug("getMenu() - returning menu instance with id matching this classes property 'menuId'");
        Domain domain = ThreadProperties.getDomain();
        MenuConfigReader configReader = new MenuConfigReader();
        Menu menu = configReader.loadMenu(domain, getId());
        return menu;
    }

    /**
     * @return Returns the selectedItemId.
     */
    public String getSelectedItemId() {
        return selectedItemId;
    }

    /**
     * @param selectedItemId
     *            The selectedItemId to set.
     */
    public void setSelectedItemId(final String selectedItemId) {
        this.selectedItemId = selectedItemId;
    }

    public String getMenuItemHtml(final Menu menu, final MenuItem menuItem, final boolean submenu,
            final boolean selected, final boolean highlighted, final Locale locale) {
        StringBuffer html = new StringBuffer();
        int imageHeight = itemHeight;
        int imageWidth = itemWidth;
        if (submenu) {
            imageWidth = subItemWidth;
            imageHeight = subItemHeight;
        }

        String subStr = "";
        if (submenu) {
            subStr = ".sub";
        }

        String selStr = "";
        if (selected) {
            selStr = ".selected";
        }

        String code = "menu" + subStr + "." + menu.getId() + selStr;
        String captionText = CoreServiceLocator.getPhraseProvider().getMessage(menuItem.getDescription(), locale);
        String imageSource = getContextPath() + "/dynagraphic/image.jpg?code=" + code + "&caption="
                + TextHelper.escapeHtml(captionText);

        A link = new A();
        link.setHref(getContextPath() + menuItem.getLink());
        StringBuffer imageHtml = new StringBuffer();
        imageHtml.append("<img id=\"" + "menu.item." + menuItem.getId() + "\" " + "src=\"");
        imageHtml.append(imageSource);
        imageHtml.append("\" alt=\"\" height=\"");
        imageHtml.append("" + imageHeight);
        imageHtml.append("\" width=\"");
        imageHtml.append(imageWidth);
        imageHtml.append("\" border=\"0\" ");
        imageHtml.append("/>");
        link.addElement(imageHtml.toString());

        html.append(link.toString());
        return html.toString();
    }

}
